﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;


namespace QuickHull
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    /// 

    public partial class MainWindow : Window
    {
        List<System.Drawing.Point> points = new List<System.Drawing.Point>();
        QuickHullAlgorithm qs = new QuickHullAlgorithm();
        Control cs = new Control();
        bool visSteps = false;
        SolidColorBrush brushw = new SolidColorBrush();
        SolidColorBrush brush = new SolidColorBrush();
        static Stopwatch sw = new Stopwatch();
        private static long _before;
            
        public MainWindow()
        {
            InitializeComponent();
            brushw.Color = Color.FromRgb(255, 255, 255);
            brush.Color = Color.FromRgb(251, 255, 105);
            qs.draw = drawAll;
            qs.drawIntermediateSteps = visSteps;
        }

        void keyPressed(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.S)
            {
                visSteps = !visSteps;
                qs.drawIntermediateSteps = visSteps;
               // Console.WriteLine("ich drücke S =)");
            }

            if (e.Key == Key.L)
            {
                zeichenblatt.Children.Clear();
                for (int i = 20; i < 1000;i++)
                {

                    for (int j = 20; j < 1000;j++)
                    {
                        points.Add(new System.Drawing.Point(i, j));
                       
                    }

                }
                sw.Start();
                _before = Process.GetCurrentProcess().WorkingSet64;
               // drawAllPoints();
                List<System.Drawing.Point> hullpoints = qs.quickHull(points);
                sw.Stop();
                var memoryInKb = (Process.GetCurrentProcess().WorkingSet64 - _before) / 1024.0;
                Console.WriteLine("Memory: {1}kb{0}", Environment.NewLine, memoryInKb);
                string ExecutionTimeTaken = string.Format("Minutes :{0}\nSeconds :{1}\n Mili seconds :{2}", sw.Elapsed.Minutes, sw.Elapsed.Seconds, sw.Elapsed.TotalMilliseconds);
                Console.WriteLine(ExecutionTimeTaken);
                Console.Read();

                drawHull(hullpoints);
                // Console.WriteLine("ich drücke S =)");
            }
        }

        void delegateQuickHullCalculation()
        {
            List<System.Drawing.Point> hullpoints = qs.quickHull(points);
            zeichenblatt.Children.Clear();
            drawHull(hullpoints);
            drawAllPoints();
        }

        void makePoint(object sender, MouseEventArgs e)
        {
            //debug output
            //String msg = "x:y = " + e.GetPosition(null).ToString();
            //Console.WriteLine(msg);


            points.Add(new System.Drawing.Point((int)e.GetPosition(null).X, (int)e.GetPosition(null).Y));
            List<System.Drawing.Point> hullpoints = qs.quickHull(points);
            zeichenblatt.Children.Clear();
            drawHull(hullpoints);
            drawAllPoints();

            //System.Threading.Thread t = new System.Threading.Thread(delegateQuickHullCalculation);
            //t.Start();
            //Console.WriteLine("liste" + points.Count);
            //Console.WriteLine("huelle"+hullpoints.Count);
        }

        void drawAll(List<System.Drawing.Point> convexHull)
        {
            zeichenblatt.Children.Clear();
            drawHull(convexHull);
            drawAllPoints();

            if(visSteps)
            {
                Action emptyDelegate = delegate { };
                zeichenblatt.Dispatcher.Invoke(emptyDelegate, System.Windows.Threading.DispatcherPriority.Render);
                System.Threading.Thread.Sleep(500);
            }
        }

        void drawAllPoints()
        {
            foreach (System.Drawing.Point p in points)
            {
                Ellipse elli = new Ellipse();
                elli.Height = 5;
                elli.Width = 5;
                elli.Fill = brush;

                Canvas.SetLeft(elli, p.X - 2.5);
                Canvas.SetTop(elli, p.Y - 2.5);
                zeichenblatt.Children.Add(elli);
            }
        }
        void drawHull(List<System.Drawing.Point> hullpoints)
        {
            if (hullpoints.Count > 2)
            {
                for (int i = 0; i < hullpoints.Count - 1; i++)
                {
                    Line l = new Line();
                    l.Stroke = System.Windows.Media.Brushes.White;
                    l.StrokeThickness = 2;
                    //  l.Fill = brushw;
                    l.X1 = hullpoints.ElementAt(i).X;
                    l.X2 = hullpoints.ElementAt(i + 1).X;
                    l.Y1 = hullpoints.ElementAt(i).Y;
                    l.Y2 = hullpoints.ElementAt(i + 1).Y;
                    //Canvas.SetLeft(l, points.ElementAt(i).X);
                    //Canvas.SetTop(l, points.ElementAt(i).Y);
                    //Canvas.SetRight(l, points.ElementAt(i+1).X);
                    //Canvas.SetBottom(l, points.ElementAt(i + 1).Y);
                    zeichenblatt.Children.Add(l);
                }
                Line last = new Line();
                last.Stroke = System.Windows.Media.Brushes.White;
                last.StrokeThickness = 2;
                //  last.Fill = brushw;
                last.X1 = hullpoints.ElementAt(0).X;
                last.X2 = hullpoints.ElementAt(hullpoints.Count - 1).X;
                last.Y1 = hullpoints.ElementAt(0).Y;
                last.Y2 = hullpoints.ElementAt(hullpoints.Count - 1).Y;
                zeichenblatt.Children.Add(last);
            }
        
        
        }
    }

}


